package routers

import (
	"gddgame.cc/galaxy/binocle"
	"gddgame.cc/galaxy/common/bootstrap"
	. "gddgame.cc/galaxy/common/dsl/db"
	. "gddgame.cc/galaxy/common/dsl/web"
	manager "gddgame.cc/galaxy/core/controllers/manager"

	// 用于db管理注册
	_ "gddgame.cc/galaxy/core/models"
	"gddgame.cc/galaxy/server/composer"
	"gddgame.cc/galaxy/server/web"

	// 插件注册
	_ "gddgame.cc/galaxy/binocle/plugins/monitor"
	_ "gddgame.cc/galaxy/binocle/plugins/notice"
	_ "gddgame.cc/galaxy/binocle/plugins/report"
	_ "gddgame.cc/galaxy/binocle/plugins/schedule"
	_ "gddgame.cc/galaxy/binocle/plugins/server"
	_ "gddgame.cc/galaxy/binocle/plugins/wechat"

	_ "gddgame.cc/galaxy/core/plugins/database"
	_ "gddgame.cc/galaxy/core/plugins/deploy"
	_ "gddgame.cc/galaxy/core/plugins/tools"
)

func manageToken(context web.Context) bool {
	token := context.Header("token")
	if token == "" {
		return false
	}
	result, err := manager.ValidToken(context, token)
	if err != nil {
		return false
	}
	if err := context.Set("id", result.Id); err != nil {
		return false
	}
	return true
}

func ManageAuth(builder composer.Builder, router web.Router) {
	_, authSessionMiddle := SessionAuthMiddle(builder, builder.Cache("admin"), router, "id", "Id", manageToken)
	router.Use(authSessionMiddle)
}

func ManageRouterBind(builder composer.Builder, r *SwaggerRouter) {
	auth := SessionAuthHandler(builder, builder.Cache("admin"), r.Router, "id", "Id")
	r.Security().OnFail(DefaultAuthFail)
	r.Security().Key("session", CookieLocation, SessionAuth, true)
	r.Security().Key("token", HeaderLocation, manageToken, true)

	r.Post("/auth/login", Swagger{
		Params: []Param{
			{Name: "username", In: Body},
			{Name: "password", In: Body},
		},
		Controllers: []Ctl{manager.Login, auth.Login},
		Response:    IdResponse,
		Security:    []string{},
	})

	r.Post("/auth/token", Swagger{
		Params:      []Param{{Name: "token", In: Body}},
		Controllers: []Ctl{manager.ValidToken, auth.Login},
		Response:    IdResponse,
		Security:    []string{},
	})

	r.Post("/auth/logout", Swagger{
		Controller: auth.Logout,
		Response:   ApiResponse,
	})

	r.Post("/auth/editPassword", Swagger{
		Params: []Param{
			{Name: "id", In: Cache, Type: Int},
			{Name: "password", In: Body},
		},
		Controller: manager.EditPassword,
		Response:   ApiResponse,
	})
}

func ManageHandler(path string, builder composer.Builder, router web.Router, boot *bootstrap.Boot) error {
	var core binocle.CoreClient
	builder.Factory(binocle.DefaultCore, &core)

	r := NewSwaggerRouter(path, builder, router, &SwaggerRouterConfig{
		Info: SwaggerInfo{
			Title: "",
		},
	})
	web.Restful(router)
	ManageRouterBind(builder, r)

	if err := BindPlugin(builder, core, r); err != nil {
		return err
	}
	if err := TableRouter(builder, r.Group("/db")); err != nil {
		return err
	}
	return nil
}
